﻿using System;
using System.ComponentModel.Composition;
using EnvDTE;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.TextManager.Interop;
using Red.Scripts.Options.Tool.Bar.Extensions;

namespace Red.Scripts.Options.Tool.Bar
{
    [Export]
    public class Reparse
    {
        #region Imports

        [Import]
        private Language.Scc.Connection Connection { get; set; }

        [Import]
        private IVsEditorAdaptersFactoryService EditorAdaptersFactoryService { get; set; }

        #endregion Imports

        #region C-Tor

        public Reparse()
        {
        }

        #endregion C-Tor

        #region Public Methods

        public void Initialize( OleMenuCommandService commandService )
        {
            commandService.InitializeButton( Defines.Toolbar.Guid, Defines.Toolbar.ReparseFileButtonId, ReparseFile );
            commandService.InitializeButton( Defines.Toolbar.Guid, Defines.Toolbar.ReparseSolutionButtonId, ReparseSolution );
        }

        #endregion Public Methods

        #region Private Methods

        private static IVsTextView GetIVsTextView( string filePath )
        {
            var dte = (DTE)Package.GetGlobalService( typeof( SDTE ) );
            ServiceProvider serviceProvider = new ServiceProvider( (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte );

            uint itemID;
            IVsUIHierarchy uiHierarchy;
            IVsWindowFrame windowFrame;
            if ( VsShellUtilities.IsDocumentOpen( serviceProvider, filePath, Guid.Empty, out uiHierarchy, out itemID, out windowFrame ) )
            {
                // Get the IVsTextView from the windowFrame.
                return Microsoft.VisualStudio.Shell.VsShellUtilities.GetTextView( windowFrame );
            }

            return null;
        }

        private ITextBuffer GetActiveDocumentTextBuffer()
        {
            DTE dte = (DTE)ServiceProvider.GlobalProvider.GetService( typeof( DTE ) );

            if ( dte.ActiveDocument != null )
            {
                IVsTextView textView = GetIVsTextView( dte.ActiveDocument.FullName );

                IVsTextLines lines;
                if ( textView.GetBuffer( out lines ) == VSConstants.S_OK )
                {
                    var buffer = lines as IVsTextBuffer;
                    if ( buffer != null )
                        return EditorAdaptersFactoryService.GetDataBuffer( buffer );
                }
            }

            return null;
        }

        private async void ReparseFile( object sender, EventArgs e )
        {
            ITextBuffer currentBuffer = GetActiveDocumentTextBuffer();

            if ( currentBuffer != null )
            {
                DTE dte = (DTE)ServiceProvider.GlobalProvider.GetService( typeof( DTE ) );
                await Connection.Parse( dte.ActiveDocument.FullName, currentBuffer.CurrentSnapshot, true );
            }
        }

        private async void ReparseSolution( object sender, EventArgs e )
        {
            DTE dte = (DTE)ServiceProvider.GlobalProvider.GetService( typeof( DTE ) );

            if( dte.ActiveDocument != null )
            {
                await Connection.ReparseSolution( dte.ActiveDocument.FullName );
            }
        }

        #endregion Private Methods
    }
}
